﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Configuration;
using iTunesLib;
using System.Diagnostics;
using System.Xml.Linq;
using System.IO;
using System.ComponentModel;

namespace iTunesFastForward.Genpuid
{
    class MusicDNS
    {

        private string _commandName = @"Genpuid\genpuid";
        private string _commandArgs = "{0} -xml -noanalysis {1}";

        private string _key;
        public string Key
        {
            get
            {
                if (_key == null)
                    _key = ConfigurationManager.AppSettings["MusicDNSKey"];
                return _key;
            }
        }

        private static MusicDNS _instance;
        public static MusicDNS Instance
        {
            get
            {
                if (_instance == null)
                    _instance = new MusicDNS();
                return _instance;
            }
        }

        private Dictionary<string, ITTrackInfos> _tracks;

        public ITTrackInfos[] GetTagsForSongs(BackgroundWorker bw, IITTrack[] tracks)
        {
            bw.ReportProgress(0);
            _tracks = new Dictionary<string, ITTrackInfos>();

            foreach (var track in tracks)
	        {
                if (track is IITFileOrCDTrack)
                {
                    var uri = new FileInfo(((IITFileOrCDTrack)track).Location).FullName;
                    _tracks.Add(uri, new ITTrackInfos { Track = ((IITFileOrCDTrack)track) });
                }
	        }

            var xml = SendCommandLine();

            ParseXML(xml);
            GetData(bw);

            return _tracks.Values.ToArray();
        }

        private string SendCommandLine()
        {
            string commandArgs = string.Format(_commandArgs, Key, 
                '"' + string.Join("\" \"", _tracks.Keys.ToArray()) + '"');

            var proc = new Process();
            proc.StartInfo.FileName = _commandName;
            proc.StartInfo.Arguments = commandArgs;
            proc.StartInfo.CreateNoWindow = true;
            proc.StartInfo.RedirectStandardOutput = true;
            proc.StartInfo.UseShellExecute = false;
            proc.Start();
            proc.WaitForExit();

            string output = proc.StandardOutput.ReadToEnd();
            proc.Dispose();

            return output;

        }

        private void ParseXML(string xml)
        {

            var doc = XDocument.Parse(xml);
            foreach (XElement track in doc.Element("genpuid").Descendants("track"))
            {
                string uri = new FileInfo(track.Attribute("file").Value).FullName;

                if ((track.Attribute("status") != null) && track.Attribute("status").Value == "unavailable")
                    _tracks[uri].PUID = null;
                else
                    _tracks[uri].PUID = track.Attribute("puid").Value;

            }

        }

        private void GetData(BackgroundWorker bw)
        {
            bw.ReportProgress(1);

            MusicBrainzWebService mbws = new MusicBrainzWebService();
            foreach (var t in _tracks.Values)
            {
                t.MatchedTracks = mbws.GetTrackMBIDs(t.PUID);
            }
        }

    }
}
